package com.auto.printer.utils;

import cn.hutool.core.io.FileUtil;
import com.auto.printer.common.exception.MyException;
import com.auto.printer.entity.param.QiNiuOssUploadBean;
import com.auto.printer.properties.QiNiuOssProperties;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.*;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.UUID;


@Slf4j
@Component
public class QiNiuUtils {

    /**
     * 上传注册器
     */
    private static UploadManager uploadManager = null;
    @Autowired
    ObjectMapper objectMapper;
    @Autowired
    private QiNiuOssProperties qiNiuOssProperties;

    /**
     * 初始化上传管理器
     */
    @PostConstruct
    public void init() {


        if (uploadManager == null) {
            //指定存储空间所在区域，华北region1，华南region2 ，华东 region0
//            Region region = Region.qvmHuabei();

            //初始化cfg实例，可以指定上传区域，也可以创建无参实例 , cfg = new Configuration();
            Configuration cfg = new Configuration();
            //是否指定https上传，默认true
            cfg.useHttpsDomains = false;
            //构建 uploadManager 实例
            uploadManager = new UploadManager(cfg);
        }

/*
        //上传管理器
        if (uploadManager == null) {
            // 华东 z0 华北 z1 华南 z2 北美 na0 东南亚 as0   文档：https://developer.qiniu.com/kodo/1671/region-endpoint-fq
            Configuration cfg = null;
            String area = qiNiuOssProperties.getArea();
            Region region = Region.region2();
            if (area.equals("z0")) {
                cfg = new Configuration(Zone.zone0());
            } else if (area.equals("z1")) {
                cfg = new Configuration(Zone.zone1());
            } else if (area.equals("z2")) {
                cfg = new Configuration(Zone.zone2());
            } else if (area.equals("na0")) {
                cfg = new Configuration(Zone.zoneNa0());
            } else if (area.equals("as0")) {
                cfg = new Configuration(Zone.zoneAs0());
            }
            uploadManager = new UploadManager(cfg);
        }*/
    }


    /**
     * 获取七牛云上传 token
     */
    public String getUpToken() {
        Auth auth = Auth.create(qiNiuOssProperties.getAccessKey(), qiNiuOssProperties.getSecretKey());
        return auth.uploadToken(qiNiuOssProperties.getBucket());
    }


    /**
     * 七牛云流文件上传
     *
     * @param multipartFile
     * @return java.lang.String
     * @author wangsong
     */
    public QiNiuOssUploadBean uploadMultipartFile(MultipartFile multipartFile) {
        InputStream inputStream = null;
        String targetFileName = multipartFile.getOriginalFilename();
        try {
            inputStream = multipartFile.getInputStream();
        } catch (IOException e) {
            throw new MyException("IO异常");
        }
        if (targetFileName.startsWith("/")) {
            targetFileName = targetFileName.replaceFirst("/", "");
        }
        Auth auth = Auth.create(qiNiuOssProperties.getAccessKey(), qiNiuOssProperties.getSecretKey());
        try {
            StringMap putPolicy = new StringMap();
            //putPolicy.put("callbackUrl", "http://api.example.com/qiniu/upload/callback");
            putPolicy.put("callbackBody", "key=$(key)&hash=$(etag)&bucket=$(bucket)&fsize=$(fsize)");
            String upToken = auth.uploadToken(qiNiuOssProperties.getBucket(), targetFileName, 3600, putPolicy);

            Response response = uploadManager.put(inputStream, targetFileName, upToken, null, null);
            QiNiuOssUploadBean qiNiuOssUploadBean = objectMapper.readValue(response.bodyString(), QiNiuOssUploadBean.class);
            qiNiuOssUploadBean.setUrl(qiNiuOssProperties.hosts + qiNiuOssUploadBean.getKey());
            log.info("七牛云oss文件上传成功 {}", objectMapper.writeValueAsString(qiNiuOssUploadBean));
            return qiNiuOssUploadBean;
        } catch (Exception ex) {
            log.error("七牛云oss文件上传失败 {}", ex);
        }
        return null;
    }

    public QiNiuOssUploadBean uploadFileByStream(InputStream stream, String fileName,String suffix) {
        if (fileName.startsWith("/")) {
            fileName = fileName.replaceFirst("/", "");
        }
        Auth auth = Auth.create(qiNiuOssProperties.getAccessKey(), qiNiuOssProperties.getSecretKey());
        try {
            StringMap putPolicy = new StringMap();
            //putPolicy.put("callbackUrl", "http://api.example.com/qiniu/upload/callback");
            putPolicy.put("callbackBody", "key=$(key)&hash=$(etag)&bucket=$(bucket)&fsize=$(fsize)");
            String upToken = auth.uploadToken(qiNiuOssProperties.getBucket(), fileName +"."+ suffix, 3600, putPolicy);

            Response response = uploadManager.put(stream, fileName + "."+suffix, upToken, null, null);
            QiNiuOssUploadBean qiNiuOssUploadBean = objectMapper.readValue(response.bodyString(), QiNiuOssUploadBean.class);
            qiNiuOssUploadBean.setUrl(qiNiuOssProperties.hosts + qiNiuOssUploadBean.getKey());
            log.info("七牛云oss文件上传成功 {}", objectMapper.writeValueAsString(qiNiuOssUploadBean));
            return qiNiuOssUploadBean;
        } catch (Exception ex) {
            log.error("七牛云oss文件上传失败 {}", ex);
        }
        return null;
    }


    public QiNiuOssUploadBean uploadFileByStream(InputStream stream,String suffix) {
       return uploadFileByStream(stream,generalFileName(),suffix);
    }


    public QiNiuOssUploadBean uploadFileByStream(File file) throws IOException {
        return uploadFileByStream(Files.newInputStream(file.toPath()), FileUtil.getPrefix(file),FileUtil.getSuffix(file));
    }

    private String generalFileName() {

        long l = LocalDateTime.now().toInstant(ZoneOffset.ofHours(0)).toEpochMilli();
        return l+ UUID.randomUUID().toString().substring(0,3) ;
    }


}



